package com.oceansoft.mobile.econsole.modules.dcn.dispatcher;

import com.oceansoft.mobile.econsole.modules.dcn.TaskExecutor;
import com.oceansoft.mobile.econsole.modules.dcn.entity.Command;
import com.oceansoft.mobile.econsole.modules.dcn.processor.IProcessor;
import oracle.jdbc.dcn.RowChangeDescription;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.HashMap;
import java.util.regex.Pattern;

/**
 * ClassName: AbstractDispatcher
 * Desc: 抽象分发器
 * Date： 2016/11/16
 * Created：shaom
 */
public abstract class AbstractDispatcher implements IDispatchable, Runnable {
    protected static final Pattern ACTION_PATTERN = Pattern.compile("\\d{6}");
    private static final Logger logger = LoggerFactory.getLogger(AbstractDispatcher.class);

    //业务处理执行器
    private static final TaskExecutor TASK_EXECUTOR = TaskExecutor.getInstance();

    //DCN事件数据库行记录ID
    private volatile String rowId;

    @Override
    public void dispatch(String tableName, String rowId, RowChangeDescription.RowOperation rowOperation) {
        this.rowId = rowId;
        TASK_EXECUTOR.post(this);
    }

    @Override
    public void run() {
        logger.info("===================线程[{}]处理请求开始===================", Thread.currentThread().getId());

        //1.根据ROWID加载请求命令信息
        Command command = loadCommand(rowId);
        if (null == command) {
            return;
        }

        //2.校验是否已经注册相应插件处理此请求
        IProcessor processor = lookupPlugin(command);
        if (null == processor) {
            return;
        }

        //3.调用插件结果处理逻辑
        processor.dealData(command);


        //4.重置ReqCmd
        resetReqCmd();
        logger.info("===================线程[{}]处理请求结束===================\n", Thread.currentThread().getId());
    }

    /**
     * 从前置机加载查询命令对象
     *
     * @param rowId 监听数据通知行记录ID
     * @return Command
     */
    protected abstract Command loadCommand(String rowId);

    /**
     * 根据查询命令从插件注册表中加载已注册插件
     *
     * @param command 查询命令
     * @return 实现IProcessor接口插件实例
     */
    protected abstract IProcessor lookupPlugin(Command command);


    /**
     * 查询命令重置
     */
    protected abstract void resetReqCmd();


}
